package prototipo.server.logic.user;

import java.lang.reflect.Method;
import java.util.List;

import prototipo.server.logic.LogicIF;
import prototipo.server.logic.exception.ExceptionLogic;
import prototipo.server.logic.util.Address;
import prototipo.server.logic.util.AddressIF;
import prototipo.server.logic.util.Password;
import prototipo.server.logic.util.PasswordIF;
import prototipo.server.logic.util.Phone;
import prototipo.server.logic.util.PhoneIF;

public class User implements UserIF {

	private String name;
	private Address address;
	private Phone phonePrivate;
	private Phone phoneJob;
	private RoleKind role;
	private String login;
	private Password password;
	private List<String> exceptionPermission;

	/**
	 * @param id
	 * @param name
	 * @param address
	 * @param phonePrivate
	 * @param phoneJob
	 * @param role
	 * @param login
	 * @param password
	 * @throws ExceptionLogic
	 */
	public User(String name, Address address, Phone phonePrivate,
			Phone phoneJob, RoleKind role, String login, Password password)
			throws ExceptionLogic {
		super();
		setName(name);
		setAddress(address);
		setPhonePrivate(phonePrivate);
		setPhoneJob(phoneJob);
		setRole(role);
		setLogin(login);
		setPassword(password);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) throws ExceptionLogic {
		if (name == null || name.equals(""))
			throw new ExceptionLogic("Nome vazio.", new Throwable(
					"String name is null"));
		this.name = name;
	}

	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) throws ExceptionLogic {
		if (address == null)
			throw new ExceptionLogic("Endereco vazio.", new Throwable(
					"Address is null."));
		this.address = address;
	}

	public Phone getPhonePrivate() {
		return phonePrivate;
	}

	public void setPhonePrivate(Phone phonePrivate) throws ExceptionLogic {
		/*
		 * if (phonePrivate == null) throw new
		 * ExceptionLogic("Telefone pessoal vazio.", new Throwable(
		 * "Phone is null."));
		 */
		this.phonePrivate = phonePrivate;
	}

	public Phone getPhoneJob() {
		return phoneJob;
	}

	public void setPhoneJob(Phone phoneJob) throws ExceptionLogic {
		/*
		 * if (phoneJob == null) throw new
		 * ExceptionLogic("Telefone de trabalho vazio.", new
		 * Throwable("Phone is null."));
		 */
		this.phoneJob = phoneJob;
	}

	public RoleKind getRole() {
		return role;
	}

	public void setRole(RoleKind role) {
		this.role = role;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) throws ExceptionLogic {
		if (login == null || login.equals(""))
			throw new ExceptionLogic("Login vazio.", new Throwable(
					"String login is null."));
		this.login = login;
	}

	public Password getPassword() {
		return password;
	}

	public void setPassword(Password password) throws ExceptionLogic {
		if (password == null)
			throw new ExceptionLogic("Senha vazia.", new Throwable(
					"Password is null."));
		this.password = password;
	}

	public List<String> getExceptionPermission() {
		return exceptionPermission;
	}

	public void setExceptionPermission(List<String> exceptionPermission)
			throws ExceptionLogic {
		for (String operation : exceptionPermission) {
			if (!validateOperation(operation))
				throw new ExceptionLogic("Operacao inexistente.",
						new Throwable("String operation invalidated."));
		}
		this.exceptionPermission = exceptionPermission;
	}

	public static boolean validateOperation(String operation)
			throws ExceptionLogic {
		if (operation == null)
			throw new ExceptionLogic(new Throwable("Operation String is null."));
		else {
			Method[] listMethods = LogicIF.class.getDeclaredMethods();
			for (Method method : listMethods) {
				if (method.getName().equals(operation))
					return true;
			}
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((login == null) ? 0 : login.hashCode());
		result = prime * result
				+ ((password == null) ? 0 : password.hashCode());
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof User))
			return false;
		User other = (User) obj;
		if (login == null) {
			if (other.login != null)
				return false;
		} else if (!login.equals(other.login))
			return false;
		if (password == null) {
			if (other.password != null)
				return false;
		} else if (!password.equals(other.password))
			return false;
		return true;
	}
}
